﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using Pixysoft.Framework.Noebe;

namespace Pixysoft.Framework.Security.Tokens
{
    /// <summary>
    /// 与数据库直接交互 不考虑缓存
    /// </summary>
    class TokenAccessController : ITokenAccessDesigner
    {
        private static volatile TokenAccessController instance;

        private static object syncRoot = new Object();

        public static TokenAccessController Instance
        {
            get
            {
                if (instance == null)
                {
                    lock (syncRoot)
                    {
                        if (instance == null)
                        {
                            instance = new TokenAccessController();
                        }
                    }
                }
                return instance;
            }
        }

        public bool ShutDown()
        {
            INoebeCommand command = TokenHelper.Instance.GetNoebeManager().NoebeCommand;
            command.SQL = "DELETE FROM SEC_TOKEN_ACCESSTABLE";
            return command.Execute() > 0;
        }

        public string CreateAccess(string usercode, string accessname)
        {
            if (string.IsNullOrEmpty(usercode))
                throw new Exception("missing usercode.");

            if (string.IsNullOrEmpty(accessname))
                throw new Exception("missing accessname.");


            usercode = usercode.Trim().ToUpper();

            accessname = accessname.Trim().ToUpper();

            string accesscode = TokenHelper.GeneratePrimaryKey();

            DataTable accessTb = TokenHelper.Instance.GetNoebeManager().GetEntity("SEC_TOKEN_ACCESSTABLE");
            DataRow tokenrow = accessTb.NewRow();
            tokenrow["ACCESSCODE"] = accesscode;
            tokenrow["USERCODE"] = usercode;
            tokenrow["USERNAME"] = DBNull.Value;
            tokenrow["ACCESSNAME"] = accessname;
            tokenrow["REMARK"] = DBNull.Value;
            tokenrow["CREATEDATE"] = TokenHelper.DateTimeNow;
            tokenrow["MODIDATE"] = TokenHelper.DateTimeNow;
            accessTb.Rows.Add(tokenrow);

            TokenHelper.Instance.GetNoebeManager().Session.Insert(accessTb);

            return accesscode;
        }

        public bool DeleteAccess(string usercode, string accessname)
        {
            if (string.IsNullOrEmpty(usercode))
                return false;

            if (string.IsNullOrEmpty(accessname))
                return false;


            usercode = usercode.Trim().ToUpper();

            accessname = accessname.Trim().ToUpper();

            INoebeCommand command = TokenHelper.Instance.GetNoebeManager().NoebeCommand;
            command.SQL = "DELETE FROM SEC_TOKEN_ACCESSTABLE WHERE USERCODE = :USERCODE AND ACCESSNAME = :ACCESSNAME";
            command.Parameters.Add("USERCODE", usercode);
            command.Parameters.Add("ACCESSNAME", accessname);
            return command.Execute() > 0;
        }

        public bool ClearAccess(string usercode)
        {
            if (string.IsNullOrEmpty(usercode))
                throw new Exception("missing usercode.");

            usercode = usercode.Trim().ToUpper();

            INoebeCommand command = TokenHelper.Instance.GetNoebeManager().NoebeCommand;
            command.SQL = "DELETE FROM SEC_TOKEN_ACCESSTABLE WHERE USERCODE = :USERCODE";
            command.Parameters.Add("USERCODE", usercode);
            return command.Execute() > 0;
        }

        public bool HasPermission(string usercode, string accessname)
        {
            if (string.IsNullOrEmpty(usercode))
                return false;

            if (string.IsNullOrEmpty(accessname))
                return false;

            usercode = usercode.Trim().ToUpper();

            accessname = accessname.Trim().ToUpper();

            INoebeCommand command = TokenHelper.Instance.GetNoebeManager().NoebeCommand;

            command.SQL = "SELECT COUNT(*) FROM SEC_TOKEN_ACCESSTABLE WHERE USERCODE = :USERCODE AND ACCESSNAME = :ACCESSNAME";

            command.Parameters.Add("USERCODE", usercode);

            command.Parameters.Add("ACCESSNAME", accessname);

            try
            {
                return int.Parse(command.ExecuteReader().Rows[0][0].ToString()) > 0;
            }
            catch (Exception ex)
            {
                LoggerHelper.Error("error when has permission." + accessname);

                LoggerHelper.Error(ex.ToString());

                return false;
            }
        }

        public DataTable GetAccessTable(string usercode)
        {
            if (string.IsNullOrEmpty(usercode))
                throw new Exception("missing usercode.");

            usercode = usercode.Trim().ToUpper();

            INoebeCommand command = TokenHelper.Instance.GetNoebeManager().NoebeCommand;
            command.SQL = "SELECT * FROM SEC_TOKEN_ACCESSTABLE WHERE USERCODE = :USERCODE";
            command.Parameters.Add("USERCODE", usercode);

            DataTable table = command.ExecuteReader();

            return table;
        }

        public List<string> GetAccessList(string usercode)
        {
            List<string> list = new List<string>();

            foreach (DataRow row in GetAccessTable(usercode).Rows)
            {
                list.Add(row["ACCESSNAME"].ToString());
            }

            return list;
        }


    }
}
